package server

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"

	"github.com/TarsCloud/TarsGo/tars"
	"github.com/TarsCloud/TarsGo/tars/util/conf"
	"github.com/gogf/gf/v2/util/gconv"
	"github.com/smartwalle/alipay/v3"

	// 注意：需要添加NATS依赖
	// go get github.com/nats-io/nats.go
	"github.com/nats-io/nats.go"
	hypernexusApp "github.com/wzh200x/hyperNexus/hyperNexusApp"
	hyperNexusCommon "github.com/wzh200x/hyperNexus/hyperNexusCommon"
	hypernexusnats "github.com/wzh200x/hyperNexus/hyperNexusNats"
	"github.com/wzh200x/hyperNexus/hyperNexusProtocol/commonProtocol"
	hyperNexusType "github.com/wzh200x/hyperNexus/hyperNexusType"
)

// NatsService NATS服务
type NatsService struct {
	Client *hypernexusnats.NatsClient // 使用NatsClient替代NatsServer
}

// PlatformReportMessage 平台上报消息
type PlatformReportMessage struct {
	Platform     int32             `json:"platform"`     // 平台类型
	ReportType   int32             `json:"reportType"`   // 上报类型
	PlatformArgs map[string]string `json:"platformArgs"` // 平台参数
	ReportInfo   map[string]string `json:"reportInfo"`   // 上报信息
}

// NewNatsService 创建NATS服务
func NewNatsService() *NatsService {
	return &NatsService{}
}

// Init 初始化NATS服务
func (s *NatsService) Init(comm *tars.Communicator, sConf *conf.Conf) error {
	// 创建NATS客户端
	s.Client = hypernexusnats.NewNatsClient()
	err := s.Client.Init(comm, sConf)
	if err != nil {
		return fmt.Errorf("初始化NATS客户端失败: %v", err)
	}

	// 订阅平台上报主题
	err = s.Client.Subscribe("platformReport_"+hypernexusApp.GHyperNexusApp.ProjectName, s.handlePlatformReport)
	if err != nil {
		return fmt.Errorf("订阅平台上报主题失败: %v", err)
	}

	log.Println("NATS服务已订阅platformReport主题")
	return nil
}

// InitFinish 完成初始化
func (s *NatsService) InitFinish() error {
	// NatsClient不需要额外的InitFinish操作
	return nil
}

// Close 关闭NATS服务
func (s *NatsService) Close() {
	if s.Client != nil {
		// 取消订阅
		s.Client.Unsubscribe("platformReport")
		// 关闭客户端
		s.Client.Close()
	}
}

// handlePlatformReport 处理平台上报消息
func (s *NatsService) handlePlatformReport(msg *nats.Msg) {
	// 解析消息
	var message PlatformReportMessage
	err := json.Unmarshal(msg.Data, &message)
	if err != nil {
		log.Printf("解析平台上报消息失败: %v\n", err)
		return
	}

	// 根据平台和上报类型处理
	switch message.Platform {
	case hyperNexusType.PlatformTypeByteJump:
		s.handleBytejumpReport(message.ReportType, message.PlatformArgs, message.ReportInfo)
	case hyperNexusType.PlatformTypeAlipay:
		s.handleAlipayReport(message.ReportType, message.PlatformArgs, message.ReportInfo)
	default:
		log.Printf("未知平台类型: %d\n", message.Platform)
	}

	// 如果需要回复，可以使用msg.Reply
	if msg.Reply != "" {
		response := map[string]interface{}{
			"code":    0,
			"message": "处理成功",
		}
		respData, _ := json.Marshal(response)
		// 直接使用NATS连接发布回复
		s.Client.Publish(msg.Reply, respData)
	}
}

// handleBytejumpReport 处理抖音平台上报
func (s *NatsService) handleBytejumpReport(reportType int32, platformArgs, reportInfo map[string]string) {
	switch reportType {
	case hyperNexusType.ReportTypeActionCode:
		s.handleBytejumpActionCode(platformArgs, reportInfo)
	default:
		log.Printf("未知抖音上报类型: %d\n", reportType)
	}
}

// handleAlipayReport 处理支付宝平台上报
func (s *NatsService) handleAlipayReport(reportType int32, platformArgs, reportInfo map[string]string) {
	switch reportType {
	case hyperNexusType.ReportTypeActionCode:
		s.handleAlipayActionCode(platformArgs, reportInfo)
	default:
		log.Printf("未知支付宝上报类型: %d\n", reportType)
	}
}

// handleBytejumpActionCode 处理抖音行动码上报
func (s *NatsService) handleBytejumpActionCode(platformArgs, reportInfo map[string]string) {
	// 获取DbAgentServerClient
	dbAgentClient := ServerApp.DbAgentServerClient.GetClientProxy()
	var account commonProtocol.Account
	var queryErr error
	// 判断reportInfo是否包含open_id
	if _, ok := reportInfo["open_id"]; ok {
		// 构建查询参数
		accountQuery := commonProtocol.AccountQuery{
			AccountName: reportInfo["open_id"],
		}

		// 查询账号是否存在
		account, queryErr = dbAgentClient.QueryAccount(accountQuery)
		if queryErr != nil {
			tars.GetLogger("bytejump_report").Errorf("查询抖音行动码上报账号失败: %v\n", queryErr)
			return
		}
		if account.ThirdActiveReport == 1 {
			return
		}
	}

	// 构建请求参数
	params := map[string]interface{}{
		"event_type": reportInfo["event_type"],
		"context": map[string]interface{}{
			"ad": map[string]interface{}{
				"callback": reportInfo["callback"],
			},
		},
		"timestamp": hyperNexusCommon.GetCurrentTimeMilliseconds(),
	}
	// 发送POST请求
	// 将参数转换为JSON
	jsonData, err := json.Marshal(params)
	if err != nil {
		tars.GetLogger("bytejump_report").Errorf("参数序列化失败: %v\n", err)
		return
	}
	resp, err := http.Post("https://analytics.oceanengine.com/api/v2/conversion",
		"application/json", bytes.NewBuffer(jsonData))
	if err != nil {
		tars.GetLogger("bytejump_report").Errorf("抖音行动码上报请求失败: %v\n", err)
		return
	}
	defer resp.Body.Close()

	// 读取响应体
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		tars.GetLogger("bytejump_report").Errorf("读取抖音行动码上报响应失败: %v\n", err)
		return
	}
	// 解析响应体
	var response map[string]interface{}
	err = json.Unmarshal(body, &response)
	if err != nil {
		tars.GetLogger("bytejump_report").Errorf("响应体解析失败: %v\n", err)
		return
	}
	// 检查响应状态
	if gconv.String(response["code"]) != "0" {
		tars.GetLogger("bytejump_report").Errorf("抖音行动码上报失败: %v\n", response)
		tars.GetLogger("bytejump_report").Errorf("抖音行动码上报内容: %v\n", reportInfo)
		return
	}
	if account.ID > 0 {
		account.ThirdActiveReport = 1
		// 更新到数据库
		_, err := dbAgentClient.UpdateAccount(account)
		if err != nil {
			tars.GetLogger("bytejump_report").Errorf("更新抖音行动码上报账号失败: %v\n", err)
			return
		}
	}
}

// handleAlipayActionCode 处理支付宝行动码上报
func (s *NatsService) handleAlipayActionCode(platformArgs, reportInfo map[string]string) {
	// 空方法，后续填充
	// 构建请求参数
	params := map[string]string{
		"app_id":      platformArgs["appId"],
		"code":        reportInfo["code"],
		"private_key": platformArgs["privateKey"],
		"public_key":  platformArgs["publicKey"],
	}
	client, err := alipay.New(params["app_id"], params["private_key"], true)
	if err != nil {
		tars.GetLogger("").Errorf("初始化支付宝客户端失败: %v\n", err)
		return
	}
	req := alipay.NewPayload("alipay.user.gamecenter.incrementgameaction.submit")
	req.Verify = false
	req.AddBizField("action_finish_date", hyperNexusCommon.GetCurrentTimeString())
	req.AddBizField("open_id", reportInfo["open_id"])
	req.AddBizField("action_code", reportInfo["action_code"])
	req.AddBizField("action_finish_channel", reportInfo["action_finish_channel"])
	req.AddBizField("out_biz_no", hyperNexusCommon.GenerateUUID())
	var result map[string]interface{}
	err = client.Request(context.Background(), req, &result)
	if err != nil {
		tars.GetLogger("alipay_report").Errorf("支付宝行动码上报请求失败: %v\n", err)
		return
	}
	if result["code"] != "10000" {
		tars.GetLogger("alipay_report").Errorf("支付宝行动码上报失败: %v\n", result)
		tars.GetLogger("alipay_report").Errorf("支付宝行动码上报内容: %v\n", reportInfo)
		return
	}
}
